此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
小程序登录
官方文档

- 小程序访问不走oauth2授权,所以我们要把小程序的请求自动放行,在base-weixin、base-mall的nacos配置文件中配置/api下的所有请求无需token访问,所以小程序的所有接口都要是/api/ma/xxx才能访问
## spring security 配置
security:
oauth2:
client:
client-id: weixin
client-secret: weixin
scope: server
# 无需token访问的url
release-urls:
- /api/**
- 登录接口实现,具体逻辑请读登录接口源码/api/ma/wxuser/login,登录接口会生成一个自定义session,保存在redis中,之后的每个小程序接口都要带上这个session才能访问
小程序登录成功
- 通过登录接口返回后会获得一个自定义session,小程序会将自定义session放入全局变量(joolun-ma/app.js)
api.login({
jsCode: res.code
})
.then(res => {
let wxUser = res.data
that.globalData.thirdSession = wxUser.sessionKey
that.globalData.wxUser = wxUser
resolve("success")
})
- 读joolun-ma/utils/api.js源码,可知在每次接口请求前,我们会自动给接口header中带上app-id和thirdSession(登录接口返回的自定义session),所以我们自己加接口的时间无需维护tenant-id和thirdSession
wx.request({
url: _url,
method: method,
data: data,
header: {
'app-id': wx.getAccountInfoSync().miniProgram.appId,
'thirdSession': getApp().globalData.thirdSession
}
})
小程序接口新增
- 假如要加一个商品查询接口goodsGet,在joolun-ma/utils/api.js中添加如下代码
goodsGet: (id) => {
return request('/mall/api/ma/goodsspu/' + id, 'get', null, false)
},
app.api.goodsGet(id)
.then(res => {
let goodsDetail = res.data
this.setData({
goodsDetail: goodsDetail
})
})
后台接收到接口调用后处理
- 我们统一将非后台的相关接口放在各项目的api目录下
- 我们以购物车接口为例(joolun/base-mall/base-mall-admin/src/main/java/com/joolun/cloud/mall/admin/api/ma/ShoppingCartApi.java)
/**
* 分页列表
* @param page 分页对象
* @param couponUser 电子券用户记录
* @return
*/
@GetMapping("/page")
public R getCouponUserPage(HttpServletRequest request, Page page, CouponUser couponUser) {
R checkThirdSession = BaseApi.checkThirdSession(couponUser, request);
if(!checkThirdSession.isOk()) {//检验失败,直接返回失败信息
return checkThirdSession;
}
return R.ok(couponUserService.page2(page, couponUser));
}
- 每个接口都会调用BaseApi.checkThirdSession方法校验sesion并获取当前用户信息
postman调试
- 通过上面原理介绍得知,我们只要知道thirdSession就能直接用postman调试
- thirdSession我们可以通过微信开发者工具获取,编译一下,小程序会调用登录接口,从登录接口我们可以获取到thirdSession

- postman调试

获取当前小程序用户的信息
- 以购物车查询接口(/api/ma/shoppingcart/page)为例:
我们需要通过用户ID去获取当前用户的购物车数据,先要使用接口传过来的thirdSession去得到用户ID,调用BaseApi.checkThirdSession方法即可,此方法具有校验ThirdSession和获取当前用户的信息的功能,请自行读源码
/**
* 校验ThirdSession,并获取当前用户的信息
* @param baseEntity
* @param request
* @return
*/
public static R checkThirdSession(Model<?> baseEntity, HttpServletRequest request) {
String thirdSession = request.getHeader("thirdSession");
//获取缓存中的ThirdSession
String key = WxMaConstants.THIRD_SESSION_BEGIN + ":" + thirdSession;
Object thirdSessionObj = redisTemplate.opsForValue().get(key);
if(thirdSessionObj == null) {//session过期
//返回超时错误码,触发小程序重新登录
return R.failed(MyReturnCode.ERR_60001.getCode(), MyReturnCode.ERR_60001.getMsg());
}else {
String thirdSessionStr = String.valueOf(thirdSessionObj);
ThirdSession thirdSessionData = JSONUtil.toBean(thirdSessionStr, ThirdSession.class);
String appId_session = thirdSessionData.getAppId();
String userId_session = thirdSessionData.getWxUserId();
String sessionKey_session = thirdSessionData.getSessionKey();
String openId_session = thirdSessionData.getOpenId();
String mallUserId_session = thirdSessionData.getMallUserId();
if (baseEntity instanceof WxUser) {
((WxUser) baseEntity).setAppId(appId_session);
((WxUser) baseEntity).setId(userId_session);
((WxUser) baseEntity).setSessionKey(sessionKey_session);
((WxUser) baseEntity).setOpenId(openId_session);
((WxUser) baseEntity).setMallUserId(mallUserId_session);
}else if (baseEntity instanceof ShoppingCart){
((ShoppingCart) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof PlaceOrderDTO){
((PlaceOrderDTO) baseEntity).setUserId(mallUserId_session);
((PlaceOrderDTO) baseEntity).setAppId(appId_session);
}else if (baseEntity instanceof UserAddress){
((UserAddress) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof OrderInfo){
((OrderInfo) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof UserCollect){
((UserCollect) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof PointsRecord){
((PointsRecord) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof UserInfo){
((UserInfo) baseEntity).setId(mallUserId_session);
}else if (baseEntity instanceof CouponUser){
((CouponUser) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof BargainUser){
((BargainUser) baseEntity).setUserId(mallUserId_session);
}else if (baseEntity instanceof BargainCut){
((BargainCut) baseEntity).setUserId(mallUserId_session);
}
return R.ok(baseEntity);
}
}